package com.gsafety.wellsfort.service.course;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gsafety.wellsfort.common.context.LoginContextUtil;
import com.gsafety.wellsfort.common.enums.QuestionTypeEnum;
import com.gsafety.wellsfort.common.util.ApiResponse;
import com.gsafety.wellsfort.common.util.ResultCode;
import com.gsafety.wellsfort.dao.anyineng.AnYiNengConfDAO;
import com.gsafety.wellsfort.dao.anyineng.AnYiNengDAO;
import com.gsafety.wellsfort.dao.anyineng.AnyinengOpreateLogDAO;
import com.gsafety.wellsfort.dao.course.CourseDAO;
import com.gsafety.wellsfort.dao.course.LessonPeriodDAO;
import com.gsafety.wellsfort.dao.course.StudentWorkDAO;
import com.gsafety.wellsfort.dao.course.WorkAnswerRecordDAO;
import com.gsafety.wellsfort.dao.knowledge.AnswerOptionDAO;
import com.gsafety.wellsfort.dao.knowledge.QuestionDAO;
import com.gsafety.wellsfort.dao.knowledge.WorkDAO;
import com.gsafety.wellsfort.dao.knowledge.WorkQuestionDAO;
import com.gsafety.wellsfort.dao.security.AdminDAO;
import com.gsafety.wellsfort.domain.dto.course.AnswerChoiceItemDTO;
import com.gsafety.wellsfort.domain.dto.course.MyWorkDTO;
import com.gsafety.wellsfort.domain.dto.course.WorkAnswerSheetDTO;
import com.gsafety.wellsfort.domain.model.anyineng.AnYiNeng;
import com.gsafety.wellsfort.domain.model.anyineng.AnYiNengConf;
import com.gsafety.wellsfort.domain.model.anyineng.AnyinengOpreateLog;
import com.gsafety.wellsfort.domain.model.course.StudentWork;
import com.gsafety.wellsfort.domain.model.course.WorkAnswerRecord;
import com.gsafety.wellsfort.domain.model.knowledge.AnswerOption;
import com.gsafety.wellsfort.domain.model.knowledge.Question;
import com.gsafety.wellsfort.domain.model.knowledge.Work;
import com.gsafety.wellsfort.domain.model.knowledge.WorkQuestion;
import com.gsafety.wellsfort.domain.model.security.Admin;
import com.gsafety.wellsfort.domain.vo.AnswerAnalysisVO;
import com.gsafety.wellsfort.domain.vo.MyQuestionVO;
import com.gsafety.wellsfort.domain.vo.MyWorkDetailVO;
import com.gsafety.wellsfort.domain.vo.MyWorkListVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MyWorkService {
    @Autowired(required = false)
    WorkDAO workDAO;
    @Autowired(required = false)
    AdminDAO adminDAO;
    @Autowired(required = false)
    StudentWorkDAO studentWorkDAO;
    @Autowired(required = false)
    LessonPeriodDAO lessonPeriodDAO;
    @Autowired(required = false)
    CourseDAO courseDAO;
    @Autowired(required = false)
    AnswerOptionDAO answerOptionDAO;
    @Autowired(required = false)
    QuestionDAO questionDAO;
    @Autowired(required = false)
    WorkAnswerRecordDAO workAnswerRecordDAO;
    @Autowired(required = false)
    WorkQuestionDAO workQuestionDAO;
    @Autowired(required = false)
    AnYiNengConfDAO anYiNengConfDAO;
    @Autowired(required = false)
    AnYiNengDAO anYiNengDAO;
    @Autowired(required = false)
    AnyinengOpreateLogDAO anyinengOpreateLogDAO;
    public ApiResponse<List<MyWorkListVO>> myWorkList(MyWorkDTO dtoParams) {
        ApiResponse<List<MyWorkListVO>> apiResponse = null;
        Page page = PageHelper.startPage(dtoParams.getPageNo(), dtoParams.getPageSize());
        if (LoginContextUtil.getStudent() != null) {
            dtoParams.setStudentId(LoginContextUtil.getStudent().getId());
        }
        List<MyWorkListVO> voList = workDAO.myWorkList(dtoParams);
        for (MyWorkListVO myWorkListVO : voList) {
            if (myWorkListVO.getCreator() != null) {
                Admin admin = adminDAO.selectByPrimaryKey(myWorkListVO.getCreator());
                if (admin != null) {
                    myWorkListVO.setCreatorName(admin.getName());
                }else{
                    myWorkListVO.setCreatorName("");
                }
            }
        }
        PageInfo pageInfo = new PageInfo(page);
        pageInfo.setList(voList);
        apiResponse = ApiResponse.success(voList, (int) pageInfo.getTotal());
        return apiResponse;
    }

    public ApiResponse<List<MyQuestionVO>> myWorkQuestionList(MyWorkDTO dtoParams) {
        ApiResponse<List<MyQuestionVO>> apiResponse = null;
        Page page = PageHelper.startPage(dtoParams.getPageNo(), dtoParams.getPageSize());
        List<MyQuestionVO> voList = studentWorkDAO.myWorkQuestion(dtoParams);
        if (LoginContextUtil.getStudent() != null) {
            dtoParams.setStudentId(LoginContextUtil.getStudent().getId());
        }
        List<StudentWork> stuWorkList = studentWorkDAO.workDetail(dtoParams);
        StudentWork stuWork = null;
        if (stuWorkList != null && stuWorkList.size() > 0) {
            stuWork = stuWorkList.get(stuWorkList.size() - 1);
        }
        AnswerAnalysisVO answerAnalysisVO;
        WorkAnswerRecord workAnswerRecord;
        List<AnswerOption> answerRightOptions;
        List<AnswerOption> myOptions;
        if (stuWork != null) {
            for (MyQuestionVO questionVo : voList) {
                List<AnswerOption> optionList = answerOptionDAO.selectByQuestionId(questionVo.getId());
                questionVo.setAnswerOptionList(optionList);

                //如果查看答案解析
                if (dtoParams.getIfViewAnalysis() != null && dtoParams.getIfViewAnalysis() == 1) {
                    answerAnalysisVO = AnswerAnalysisVO.builder().build();
                    workAnswerRecord = workAnswerRecordDAO.selectByStuWorkIdAndQuestionId(stuWork.getId(), questionVo.getId());
                    answerRightOptions = answerOptionDAO.selectRightByQuestionId(questionVo.getId());

                    if (answerRightOptions.size() > 0) {
                        answerAnalysisVO.setRightAnswer(AnswerOptionUtils.parseOptionToString(answerRightOptions));
                        answerAnalysisVO.setRightAnswerIds(AnswerOptionUtils.parseOptionIdToString(answerRightOptions));
                    }
                    if (workAnswerRecord != null) {
                        String answerArrayStr = workAnswerRecord.getAnswerId() != null ? workAnswerRecord.getAnswerId() + "" : "" + "," + workAnswerRecord.getAnswerIds() != null ? workAnswerRecord.getAnswerIds() : "";
                        String[] optionIds = answerArrayStr.split(",");
                        myOptions = answerOptionDAO.selectByOptionIds(optionIds);
                        if (myOptions.size() > 0) {
                            answerAnalysisVO.setMyAnswer(AnswerOptionUtils.parseOptionToString(myOptions));
                            answerAnalysisVO.setMyAnswerIds(AnswerOptionUtils.parseOptionIdToString(myOptions));
                        }
                        if(answerAnalysisVO.getRightAnswerIds()!=null){
                            answerAnalysisVO.setIsRight(answerAnalysisVO.getRightAnswerIds().equals(answerAnalysisVO.getMyAnswerIds()) ? "正确" : "错误");
                        }else{
                            answerAnalysisVO.setIsRight("错误");
                        }
                    } else {
                        answerAnalysisVO.setRightAnswer(AnswerOptionUtils.parseOptionToString(answerRightOptions));
                        answerAnalysisVO.setRightAnswerIds(AnswerOptionUtils.parseOptionIdToString(answerRightOptions));
                        answerAnalysisVO.setIsRight("未答");
                    }
                    answerAnalysisVO.setAnalyzing(questionVo.getAnalyzing());
                    questionVo.setAnalyzing("");

                    questionVo.setAnswerAnalysisVO(answerAnalysisVO);
                }
            }
        }
        //答题开始时间
        stuWork.setStartTime(new Date());
        studentWorkDAO.updateByPrimaryKeySelective(stuWork);
        PageInfo pageInfo = new PageInfo(page);
        pageInfo.setList(voList);
        apiResponse = ApiResponse.success(voList, (int) pageInfo.getTotal());
        return apiResponse;
    }



    public ApiResponse<MyWorkDetailVO> myWorkDetail(MyWorkDTO dtoParams) {
        ApiResponse<MyWorkDetailVO> apiResponse = null;
        try {
            if (LoginContextUtil.getStudent() != null) {
                dtoParams.setStudentId(LoginContextUtil.getStudent().getId());
            } else {
                return ApiResponse.error(ResultCode.ERROR, "学生未登录");
            }
            List<StudentWork> studentWorkList = studentWorkDAO.workDetail(dtoParams);
            StudentWork studentWork = null;
            if (studentWorkList != null && studentWorkList.size() > 0) {
                studentWork = studentWorkList.get(studentWorkList.size() - 1);
                MyWorkDetailVO myWorkDetailVo = new MyWorkDetailVO();
                BeanUtils.copyProperties(studentWork, myWorkDetailVo);
                if (studentWork.getWorkId() != null) {
                    myWorkDetailVo.setWork(workDAO.selectByPrimaryKey(studentWork.getWorkId()));
                }
                if (studentWork.getLessonPeriodId() != null) {
                    myWorkDetailVo.setLessonPeriod(lessonPeriodDAO.selectByPrimaryKey(studentWork.getLessonPeriodId()));
                }
                if (studentWork.getCourseId() != null) {
                    myWorkDetailVo.setCourse(courseDAO.selectByPrimaryKey(studentWork.getLessonPeriodId()));
                }
                apiResponse = ApiResponse.success(myWorkDetailVo);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            apiResponse = ApiResponse.error(ResultCode.ERROR);
        }
        return apiResponse;
    }

    public ApiResponse<WorkAnswerSheetDTO> submitWorkQuAnswer(WorkAnswerSheetDTO workAnswerSheetDTO) {
        ApiResponse<WorkAnswerSheetDTO> apiResponse = null;
        try {
            Integer studentId;
            if (LoginContextUtil.getStudent() != null) {
                studentId = LoginContextUtil.getStudent().getId();
            } else {
                return ApiResponse.error(ResultCode.ERROR, "学生未登录");
            }
            MyWorkDTO dtoParams = new MyWorkDTO();
            dtoParams.setStudentId(studentId);
            dtoParams.setWorkId(workAnswerSheetDTO.getWorkId());
            dtoParams.setWorkPublishId(workAnswerSheetDTO.getWorkPublishId());
            List<StudentWork> studentWorkList = studentWorkDAO.workDetail(dtoParams);
            StudentWork studentWork = null;
            List<WorkAnswerRecord> list = null;
            if (studentWorkList != null && studentWorkList.size() > 0) {
                studentWork = studentWorkList.get(studentWorkList.size() - 1);
                if (studentWork != null) {
                    list = workAnswerRecordDAO.selectByStuWorkId(studentWork.getId());
                }
            }
            //如果答过一遍,提交答题卡清除原来的答题
            if (list != null && list.size() > 0) {
                workAnswerRecordDAO.deleteByStuWorkId(studentWork.getId());
            }
            List<AnswerChoiceItemDTO> answerChoiceItemDTOS = workAnswerSheetDTO.getAnswerChoiceItemDTOList();
            WorkAnswerRecord answerRecord;
            Question question;
            AnswerOption answerOption;
            List<AnswerOption> rightAnswerOptionList;
            BigDecimal score=BigDecimal.ZERO;
            Work work = workDAO.selectByPrimaryKey(studentWork.getWorkId());
            WorkQuestion workQuestion;
            for (AnswerChoiceItemDTO choiceItem : answerChoiceItemDTOS) {
                question = questionDAO.selectByPrimaryKey(choiceItem.getQuestionId());
                workQuestion=workQuestionDAO.selectByWorkIdAndQuestionId(work.getId(),choiceItem.getQuestionId());
                answerRecord = new WorkAnswerRecord();
                //单选题或者判断题
                if (question.getExamType().intValue() == QuestionTypeEnum.SINGLE_ELECTION.value
                        || question.getExamType().intValue() == QuestionTypeEnum.JUDGE_QUESTION.value
                ) {
                    answerOption=answerOptionDAO.selectByPrimaryKey(choiceItem.getOptionId());
                    answerRecord.setAnswerId(choiceItem.getOptionId());
                    if(answerOption.getIsRight()==1){
                        score=score.add(workQuestion.getScore());
                    }
                //多选题
                } else if (question.getExamType().intValue() == QuestionTypeEnum.MULTIPLE_CHOICE.value) {
                    answerRecord.setAnswerIds(choiceItem.getOptionIds());
                    rightAnswerOptionList=answerOptionDAO.selectRightByQuestionId(choiceItem.getQuestionId());
                    if(rightAnswerOptionList.size()>0){
                        Set<String> rightSet=AnswerOptionUtils.parseOptionIdToHashSet(rightAnswerOptionList);
                        if(choiceItem.getOptionIds()!=null){
                            List<String> choiceArray = AnswerOptionUtils.stringToList(choiceItem.getOptionIds());
                            if(rightSet.containsAll(choiceArray)&&choiceArray.size()==rightSet.size()){
                                score=score.add(workQuestion.getScore());
                            }
                        }

                    }
                //简答题
                } else if (question.getExamType().intValue() == QuestionTypeEnum.SHORT_ANSWER.value) {
                    answerRecord.setAnswerContents(choiceItem.getAnswerContents());
                }
                answerRecord.setQuestionId(question.getId());
                answerRecord.setStudentWorkId(studentWork.getId());
                answerRecord.setAnswerTime(new Date());
                workAnswerRecordDAO.insertSelective(answerRecord);
            }
            //答题完成后,修改作业信息
            studentWork.setFinishState((byte) 1);
            studentWork.setEndTime(new Date());
            studentWork.setScore(score);

            if(work!=null&&work.getPassingScore()!=null){
                if(work.getPassingScore().doubleValue()<=score.doubleValue()){
                    studentWork.setIsPassed((byte)1);
                }else{
                    studentWork.setIsPassed((byte)0);
                }
            }
            studentWorkDAO.updateByPrimaryKeySelective(studentWork);
            //安意能作业评估
            AnyinengOpreateLog opreateLog;
            AnYiNengConf anYiNengConf = anYiNengConfDAO.selectAnYiNengConf();
            AnYiNeng anYiNeng=anYiNengDAO.selectByStudentId(studentId);
            if(anYiNeng!=null&&(studentWork.getIsCountAyn()==null||studentWork.getIsCountAyn()==0)){
                Integer finishNum=studentWorkDAO.countFinishByState(studentId,1,anYiNeng.getCreateTime());
                double C1=0,C2=0;
                if(finishNum>=anYiNengConf.getWorkAddMax().intValue()){
                    C1=0;
                }else{
                    C1=anYiNengConf.getWorkAddUp().intValue();
                }

                if(work.getCurrentTotalScore()!=null&&work.getCurrentTotalScore().intValue()!=0){
                    C2=score.doubleValue()/work.getCurrentTotalScore().doubleValue();
                }
                double C=C1+anYiNengConf.getWorkResultScore().doubleValue()*C2;
                BigDecimal aynVal=anYiNeng.getVal().add(BigDecimal.valueOf(C));
                if(aynVal.intValue()>1000){
                    aynVal=BigDecimal.valueOf(1000);
                }
                //修改安意分值
                anYiNeng.setVal(aynVal);
                anYiNeng.setUpdateTime(new Date());
                anYiNeng.setModified(studentId);
                anYiNengDAO.updateByPrimaryKeySelective(anYiNeng);
                //记录安意能操作日志
                opreateLog=AnyinengOpreateLog.builder().anyinengId(anYiNeng.getId())
                        .datetime(new Date())
                        .operateType(2)
                        .remark("作业评估")
                        .val(BigDecimal.valueOf(C)).build();
                anyinengOpreateLogDAO.insertSelective(opreateLog);

                studentWork.setIsCountAyn((byte)1);
                studentWorkDAO.updateByPrimaryKeySelective(studentWork);
            }
            apiResponse = ApiResponse.success(workAnswerSheetDTO);
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            e.printStackTrace();
        }
        return apiResponse;
    }
}
